package model;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author Alexander Shidlovsky
 */
public class Stack implements Comparable<Stack> {
	private ProductType productType;
	private int numberOfTrays;
	private TaskInfo currentProcess;
	private Location location;
	private List<TaskInfo> tasks;

	private boolean finished = false;
	private boolean wasted = false;

	public Stack(ProductType productType, int numberOfTrays, Location location) {
		this(productType, numberOfTrays);
		setLocation(location);
	}

	public Stack(ProductType productType, int numberOfTrays) {
		setProductType(productType);
		this.numberOfTrays = numberOfTrays;

		tasks = new ArrayList<TaskInfo>();

		List<Process> recipe = productType.getRecipe();
		for (int i = 0; i < recipe.size(); i++) {
			tasks.add(new TaskInfo(recipe.get(i)));
		}

		if (tasks != null && tasks.size() > 0) {
			currentProcess = tasks.get(0);
			currentProcess.setStartTime(new Date(System.currentTimeMillis()));
		}
	}

	public boolean isFinished() {
		return finished;
	}

	public boolean isWasted() {
		return wasted;
	}

	public void setFinished(boolean finished) {
		this.finished = finished;
	}

	public void setWasted(boolean wasted) {
		this.wasted = wasted;
	}

	public ProductType getProductType() {
		return productType;
	}

	public void setProductType(ProductType productType) {
		if (this.productType != productType) {
			if (this.productType != null) {
				this.productType.removeStack(this);
			}
			this.productType = productType;
			productType.addStack(this);
		}
	}

	public int getNumberOfTrays() {
		return numberOfTrays;
	}

	public void setNumberOfTrays(int numberOfTrays) {
		this.numberOfTrays = numberOfTrays;
	}

	public TaskInfo getCurrentProcess() {
		return currentProcess;
	}

	public void setCurrentProcess(TaskInfo currentProcess) {
		this.currentProcess = currentProcess;
	}

	public boolean isProcessRunning() {
		return currentProcess == null ? false : true;
	}

	public Location getLocation() {
		return location;
	}

	public void setLocation(Location location) {
		this.location = location;
		if (location != null)
			location.setStack(this);
	}

	public void removeLocation() {
		if (location != null)
			location.removeStack();
		location = null;
	}

	/**
	 * Sets start time for the current process
	 */
	public void startCurrentProcess() {
		currentProcess.setStartTime(new Date(System.currentTimeMillis()));
	}

	public boolean finishCurrentProcess() {
		if (currentProcess != null)
			return currentProcess.finishProcess();

		return true;
	}

	public TaskInfo getNextProcess() {
		int index = tasks.indexOf(currentProcess);
		if (index + 1 >= tasks.size())
			return null;
		else
			return (tasks.get(index + 1));

	}

	public List<TaskInfo> getTasks() {
		return new ArrayList<TaskInfo>(tasks);
	}

	@Override
	public String toString() {
		return productType.getName();
	}

	/**
	 * Used for sorting stacks by time which is left for current process
	 */
	@Override
	public int compareTo(Stack comp) {
		if (comp.getCurrentProcess() == null && this.currentProcess == null)
			return 0;

		if (comp.getCurrentProcess() == null)
			return -1;

		if (this.currentProcess == null)
			return 1;

		if (this.currentProcess.calculateTimeLeft() <= comp.getCurrentProcess()
				.calculateTimeLeft()) {
			return -1;
		}

		return 1;
	}
}
